from abc import ABC, abstractmethod
from typing import List

class IClosable(ABC):
    @abstractmethod
    def closed(self) -> bool:
        pass
    @abstractmethod
    def close(self) -> bool:
        pass

class IReadable(ABC):
    @abstractmethod
    def readable(self) -> bool:
        pass

class IBinaryReadable(IReadable):
    @abstractmethod
    def read(self, size: int = -1) -> bytes | None:
        pass

class ITextReadable(IReadable):
    @abstractmethod
    def encoding(self) -> str | None:
        pass 

    @abstractmethod
    def read(self, count: int = -1) -> str | None:
        pass

    @abstractmethod
    def read_line(self, size: int = -1) -> str | None:
        pass










class IWritable(ABC):
    @abstractmethod
    def writable(self) -> bool:
        pass
    @abstractmethod
    def flush(self) -> bool:
        pass

class IBinaryWritable(IWritable):
    @abstractmethod
    def write(self, buffer: bytes) -> int:
        pass

class ITextWritable(IWritable):
    @abstractmethod
    def encoding(self) -> str | None:
        pass 

    @abstractmethod
    def write(self, s: str) -> int:
        pass

class AbstractBinaryReader(IClosable, IBinaryReadable):
    pass
class AbstractTextReader(IClosable, ITextReadable):
    pass
class AbstractBinaryWriter(IClosable, IBinaryWritable):
    pass
class AbstractTextWriter(IClosable, ITextWritable):
    pass

import unittest 
class TestStreamable(unittest.TestCase):
    class BinaryFile(AbstractBinaryReader):
        def __init__(self):
            self.__opened = True
        def closed(self) -> bool:
            return not self.__opened
        def close(self) -> bool:
            if self.__opened:
                self.__opened = False
                return True
            return False
        def readable(self) -> bool:
            return True
        def read(self, size: int = -1) -> bytes | None:
            return b"BinaryFile"


    def test_binary_reader(self):
        reader = TestStreamable.BinaryFile()
        self.assertFalse(reader.closed())
        self.assertTrue(reader.readable())
        self.assertTrue(len(reader.read()) > 0)
        self.assertTrue(reader.close())

#TODO: unittest for all interface
